#include "MessageQueue.h"
#include "OssManger.h"

#include <SimpleAmqpClient/SimpleAmqpClient.h>
#include <workflow/WFTaskFactory.h>
#include <sstream>
#include <iostream>


namespace
{

    //默认的host
    constexpr const char* DEFAULT_HOST = "127.0.0.1";
    //默认的端口
    constexpr const unsigned short DEFAULT_PORT = 5672;
    //默认的用户名
    constexpr const char* DEFAULT_USERNAME = "guest";
    //默认的密码
    constexpr const char* DEFAULT_PASSWORD = "guest";
    //默认的虚拟host
    constexpr const char* DEFAULT_VHOST = "/";
    //默认的exchange的名字
    constexpr const char* DEFAULT_EXCHANGE = "myexchange";
    //默认使用的路由key
    constexpr const char* DEFAULT_ROUTING_KEY = "v3";
    //默认http的url,注意/需要编码
    constexpr const char* DEFAULT_URL = "amqp://guest:guest@localhost:5672/%2f";
    //默认使用的queue的名字
    constexpr const char* DEFAULT_QUEUE_NAME = "CloudDisk";

    void handleMessage(const l::MessageQueue::JSON& message) {

        using std::string;

        string objectName{ message["objectName"] };
        string filePath{ message["filePath"] };
#ifdef BUG
        std::cout << "bojectName:" << objectName << std::endl;
        std::cout << "filePath:" << filePath << std::endl;
#endif

        //创建一个异步的任务去执行
        // 创建 GoTask
        WFGoTask* task = WFTaskFactory::create_go_task("queue", [filePath, objectName]()
            {
                l::OssManger::upload_backup_by_io(filePath, objectName);
            });
        task->start();  // 交给框架异步执行

    }

}//end of Anonymous namespace 

namespace l
{

    void MessageQueue::produce_message(const JSON& srcMessage) {

        using std::string;

        string host{ DEFAULT_HOST };
        int port = DEFAULT_PORT;
        string username{ DEFAULT_USERNAME };
        string password{ DEFAULT_PASSWORD };
        string vhost{ DEFAULT_VHOST };

        // 创建Channel
        AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create(host, port, username, password, vhost);
        // 构建消息
        AmqpClient::BasicMessage::ptr_t message = AmqpClient::BasicMessage::Create(srcMessage.dump());
        // 发布消息
        string exchange = DEFAULT_EXCHANGE;
        string routingKey = DEFAULT_ROUTING_KEY;
        channel->BasicPublish(exchange, routingKey, message);

    }

    void MessageQueue::produce_message(const std::string& srcMessage) {

        using std::string;

        string host = DEFAULT_HOST;
        int port = DEFAULT_PORT;
        string username = DEFAULT_USERNAME;
        string password = DEFAULT_PASSWORD;
        string vhost = DEFAULT_VHOST;

        // 创建Channel
        AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create(host, port, username, password, vhost);
        // 构建消息
        AmqpClient::BasicMessage::ptr_t message = AmqpClient::BasicMessage::Create(srcMessage);
        // 发布消息
        string exchange = DEFAULT_EXCHANGE;
        string routingKey = DEFAULT_ROUTING_KEY;
        channel->BasicPublish(exchange, routingKey, message);

    }


    void MessageQueue::consume_message() {

        using std::string;
        using namespace AmqpClient;

        string uri{ DEFAULT_URL };
        AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::CreateFromUri(uri);

        AmqpClient::Envelope::ptr_t envelope;
        const std::string& queue{ DEFAULT_QUEUE_NAME };

        channel->BasicConsume(queue);

        while (true) {
            Envelope::ptr_t envelope = channel->BasicConsumeMessage();
            // 处理消息
            if (envelope && envelope->Message()) {

                //取出body，并创建出一个JSON(利用一个iostream创建)

                std::istringstream iss{ envelope->Message()->Body() };
                JSON message{};
                iss >> message;
                //不要构造成字符串的json，不好解析
                // JSON message = envelope->Message()->Body();
#ifdef BUG
                std::cout << "message json:" << message.dump(2) << std::endl;
#endif
                //处理消息
                handleMessage(message);

            }
        }

    }

}//end of namespace l